package bean;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.jdom.JDOMException;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.FlowEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.StreamedContent;

import service.GeraSoapUIXML;
import service.ObjectFactory;
import utils.TestSuiteLazyList;
import utils.Utils;
import entity.Assertion;
import entity.Config;
import entity.Configuration;
import entity.Entry;
import entity.Method;
import entity.Parameters;
import entity.Resource;
import entity.RestRequest;
import entity.SoapuiProject;
import entity.TestCase;
import entity.TestStep;
import entity.TestSuite;
import facade.SoapuiProjectFacade;

@ManagedBean
@SessionScoped
public class ProjectWizard implements Serializable{

	private static final long serialVersionUID = 1L;

	private StreamedContent file;
	private SoapuiProject project = new SoapuiProject();
	private TestSuite testSuite;
	private TestStep testStep;
	private TestCase testCase;
	private Config config;
	private RestRequest restRequest;
	private Assertion assertionObj;
	private Configuration configuration;
	private Parameters parameters;
	private Entry entry;
	private GeraSoapUIXML geraSoapUIXML = new GeraSoapUIXML();
	private List<TestSuite> testSuites = new ArrayList<TestSuite>();
	private List<TestSuite> testSuitesInter = new ArrayList<TestSuite>();
	private List<TestSuite> testSuitesGerXml = new ArrayList<TestSuite>();
	private LazyDataModel<TestSuite> testeSDataModel = null;
	private List<Resource> resources = new ArrayList<Resource>();
	private List<Method> methodsInter = new ArrayList<Method>();
	private List<TestCase> testCases = new ArrayList<TestCase>();
	private List<SoapuiProject> soapuiProjects = new ArrayList<SoapuiProject>();
	private ObjectFactory factory = new ObjectFactory();
	private SoapuiProjectFacade projectFacade;
	private String httpMethod;
	private String nameXml;
	private String deployPaste;
	private String path;
	private boolean skip;  
    
    private static Logger logger = Logger.getLogger(ProjectWizard.class.getName());
    
    
    @PostConstruct
    public void init(){
        System.out.println(" Bean executado! ");
        project = new SoapuiProject();
		testSuite = new TestSuite();
		testStep = new TestStep();
		testCase = new TestCase();
		config = new Config();
		restRequest = new RestRequest();
		assertionObj = new Assertion();
		configuration = new Configuration();
		parameters = new Parameters();
		entry = new Entry();
		soapuiProjects = new ArrayList<SoapuiProject>();
		
		
    }



    
    public void save() throws JDOMException, IOException {
    	List<TestSuite> Tsuites = new ArrayList<TestSuite>();
    	Tsuites = getProjectFacade().getProjectsByNameTestSuite(project.getName());
    	project.setTestSuiteList(Tsuites);
        geraSoapUIXML.getMethodXml(project,getDeployPaste());
        FacesMessage msg = new FacesMessage("XML GENERATED WITH SUCCESS !");  
        FacesContext.getCurrentInstance().addMessage(null, msg);  
    }  
      
  
    public String doListProject(){
    	return "/listProject.jsf";
    }
    
    public String doGenerateXML(){
    	return "/generateXML.jsf";
    }
    
    
	public SoapuiProject getProject() {
		project.setTestSuite(testSuite);
		project.getTestSuite().setTestCase(testCase);
		project.getTestSuite().getTestCase().setTestStep(testStep);
		project.getTestSuite().getTestCase().getTestStep().setConfig(config);
		project.getTestSuite().getTestCase().getTestStep().getConfig().setRestRequest(restRequest);
		project.getTestSuite().getTestCase().getTestStep().getConfig().getRestRequest().setParameters(parameters);
		project.getTestSuite().getTestCase().getTestStep().getConfig().getRestRequest().getParameters().setEntry(entry);
		project.getTestSuite().getTestCase().getTestStep().getConfig().getRestRequest().setAssertionObj(assertionObj);
		project.getTestSuite().getTestCase().getTestStep().getConfig().getRestRequest().getAssertionObj().setConfiguration(configuration);
		project.setTestSuiteList(testSuitesInter);
		
		return project;
	}

    public void tableBuild() throws JDOMException, IOException{
	   	
	   	getProjectFacade().createSoapuiProject(getProject(),getProject().getTestSuite(),configuration);
	   	FacesMessage msg = new FacesMessage("Creating Test Suite");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
        testSuitesInter = getProjectFacade().getListTableBuild();
        //save();
	   	//project = new SoapuiProject();
	   	
    }

    public void handleFileUpload(FileUploadEvent event) throws FileNotFoundException, IOException{

		
		Utils utils = new Utils(); 
		String nomeArquivo =  event.getFile().getFileName();
		nameXml =  event.getFile().getFileName();
		
		 try {
			    String extensao = nomeArquivo.substring(nomeArquivo.lastIndexOf("."), nomeArquivo.length());  
	            utils.copyFile(project.getName()+extensao, event.getFile().getInputstream(),getDeployPaste());
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
		FacesMessage msg = new FacesMessage("Success "+event.getFile().getFileName()+" loaded."); // mensagem pra saber se ouve sucesso 
		FacesContext.getCurrentInstance().addMessage(null, msg);  
		

	}

  
    public void populaTabela() throws JDOMException{
    	testSuitesGerXml = getProjectFacade().getProjectsByNameTestSuite(getProject().getName());
    	
    }
    
    public void ListAjax() throws JDOMException{
    	for(TestCase testCase: testCases){
    		if(testCase.getTestSuite().getProject().getName().equals(project.getName())){
    		getTestSuite().setName(testCase.getTestSuite().getName());
    		getTestCase().setName(testCase.getName());
    		}
    		getListResources();
    	}
    	
    }
    
    public List<SoapuiProject> getListProjetcs(){
		return getProjectFacade().getListSoapuiProjects();
	}
    
    public List<Resource> getListResources() throws JDOMException{
        ObjectFactory objectFactory = new ObjectFactory(project,getDeployPaste());
    	resources = objectFactory.createResource();
    	for (Resource resource : resources) {
			String pathXml = resource.getPath();
			resource.setPath(getPath()+"/"+pathXml);
		}
    	return resources;
    }
    
    public List<Method> getListMethods() throws JDOMException{
        ObjectFactory objectFactory = new ObjectFactory(project,getDeployPaste());
    	methodsInter = objectFactory.listMethods();
    	
    	return methodsInter;
    }
    
    
    public void interatorComboTestCase() throws JDOMException{
    	
    	//testSuites = new ArrayList<TestSuite>();
    	TestCase Tcase = new TestCase();
    	Tcase.setName(testCase.getName());
    	for(TestSuite testSuite : testSuites){
    		if(testSuite.getName().equals(getTestSuite().getName())){
    			Tcase.setTestSuite(testSuite);
    		}
    	}
    	
    	
    	testCases.add(Tcase);
    	FacesMessage msg = new FacesMessage("Success Creating Test Case");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    
    public void interatorComboTestSuite() throws JDOMException{
    	//factory.createResource();
    	//testSuites = new ArrayList<TestSuite>();
    	TestSuite Tsuite = new TestSuite();
    	Tsuite.setName(testSuite.getName());
    	Tsuite.setProject(getProject());
    	Tsuite.setTestCase(getTestCase());
    	testSuites.add(Tsuite);
    	FacesMessage msg = new FacesMessage("Success Creating Test Suite");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
    	
    }
    
    public void createProjectName() throws JDOMException{
    	//factory.createResource();
    	//testSuites = new ArrayList<TestSuite>();
    	SoapuiProject soapuiProject = new SoapuiProject();
    	soapuiProject.setName(project.getName());
    	soapuiProjects.add(soapuiProject);
    	FacesMessage msg = new FacesMessage("Success Creating Project");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    
	public void setProject(SoapuiProject project) {
		this.project = project;
	}

	public boolean isSkip() {
		return skip;
	}

	public void setSkip(boolean skip) {
		this.skip = skip;
	} 
	
	public GeraSoapUIXML getGeraSoapUIXML() {
		return geraSoapUIXML;
	}

	public void setGeraSoapUIXML(GeraSoapUIXML geraSoapUIXML) {
		this.geraSoapUIXML = geraSoapUIXML;
	}
	
	public TestSuite getTestSuite() {
		if(testSuite == null){
			testSuite = new TestSuite();
		}
		return testSuite;
	}

	public void setTestSuite(TestSuite testSuite) {
		this.testSuite = testSuite;
	}
    
	public List<TestSuite> getTestSuites() {
		return testSuites;
	}

	public void setTestSuites(List<TestSuite> testSuites) {
		this.testSuites = testSuites;
	}

	public TestStep getTestStep() {
		return testStep;
	}

	public void setTestStep(TestStep testStep) {
		this.testStep = testStep;
	}
	
	public Config getConfig() {
		return config;
	}

	public void setConfig(Config config) {
		this.config = config;
	}
	
	public RestRequest getRestRequest() {
		return restRequest;
	}

	public void setRestRequest(RestRequest restRequest) {
		this.restRequest = restRequest;
	}
	
	public Assertion getAssertionObj() {
		if(assertionObj == null){
			assertionObj = new Assertion();
		}
		return assertionObj;
	}

	public void setAssertionObj(Assertion assertionObj) {
		this.assertionObj = assertionObj;
	}
	
	public Configuration getConfiguration() {
		return configuration;
	}

	public void setConfiguration(Configuration configuration) {
		this.configuration = configuration;
	}
	
	public Parameters getParameters() {
		return parameters;
	}

	public void setParameters(Parameters parameters) {
		this.parameters = parameters;
	}
	
	public Entry getEntry() {
		return entry;
	}

	public void setEntry(Entry entry) {
		this.entry = entry;
	}
	
	public TestCase getTestCase() {
		return testCase;
	}

	public void setTestCase(TestCase testCase) {
		this.testCase = testCase;
	}
	
	public List<SoapuiProject> getSoapuiProjects() {
		if(soapuiProjects == null){
			soapuiProjects = new ArrayList<SoapuiProject>();
		}
		return soapuiProjects;
	}

	public void setSoapuiProjects(List<SoapuiProject> soapuiProjects) {
		this.soapuiProjects = soapuiProjects;
	}

	public ObjectFactory getFactory() {
		return factory;
	}

	public void setFactory(ObjectFactory factory) {
		this.factory = factory;
	}


	public List<TestCase> getTestCases() {
		return testCases;
	}

	public void setTestCases(List<TestCase> testCases) {
		this.testCases = testCases;
	}

	public List<TestSuite> getTestSuitesInter() {
		if(testSuitesInter ==  null){
			testSuitesInter = new ArrayList<TestSuite>();
		}
		return testSuitesInter;
	}

	public void setTestSuitesInter(List<TestSuite> testSuitesInter) {
		this.testSuitesInter = testSuitesInter;
	}

	public SoapuiProjectFacade getProjectFacade() {	
		if(projectFacade == null){
			projectFacade = new SoapuiProjectFacade();
		}
		return projectFacade;
	}

	public LazyDataModel<TestSuite> getAllTestSuite() {
        if (testeSDataModel == null) {
        	testeSDataModel = new TestSuiteLazyList();
        }
 
        return testeSDataModel;
    }

	public List<TestSuite> getTestSuitesGerXml() {
		return testSuitesGerXml;
	}


	public void setTestSuitesGerXml(List<TestSuite> testSuitesGerXml) {
		this.testSuitesGerXml = testSuitesGerXml;
	}	

	public List<Resource> getResources() {
		if(resources == null){
			resources = new ArrayList<Resource>();
		}
		return resources;
	}

	public void setResources(List<Resource> resources) {
		this.resources = resources;
	}


	public String onFlowProcess(FlowEvent event) { 
		testSuitesInter = getProjectFacade().getListTableBuild(); 
		logger.info("NOME: - "+project.getName());
        logger.info("Current wizard step:" + event.getOldStep());  
        logger.info("Next step:" + event.getNewStep());  
          
        if(skip) {  
            skip = false;   //reset in case user goes back  
            return "confirm";  
        }  
        else {  
            return event.getNewStep();  
        }  
    }

	public StreamedContent getFile() throws FileNotFoundException {
		String arquivo = project.getName()+"SOAP.xml";
		String caminho = getDeployPaste()+project.getName()+"\\"+arquivo;
       
        
        InputStream stream = new FileInputStream(caminho);
        file = new DefaultStreamedContent(stream, "application/xml", arquivo);
        
        return file;  
		
	}
	
	public void setFile(StreamedContent file) {
		this.file = file;
	}

	public String getHttpMethod() {
		return httpMethod;
	}

	public void setHttpMethod(String httpMethod) {
		this.httpMethod = httpMethod;
	}

	public String getNameXml() {
		return nameXml;
	}

	public void setNameXml(String nameXml) {
		this.nameXml = nameXml;
	}

	public String getDeployPaste() {
		if(deployPaste==null){
			deployPaste = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
		}
		return deployPaste;
	}

	public void setDeployPaste(String deployPaste) {
		this.deployPaste = deployPaste;
	}

	public String getPath() {
		if(path==null){
			path = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
		}
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}


	public List<Method> getMethodsInter() {
		return methodsInter;
	}


	public void setMethodsInter(List<Method> methodsInter) {
		this.methodsInter = methodsInter;
	}  
    
	
}
